#!/bin/bash
###############################################################################
#       脚本名称: utils.sh
#       功能描述: utils模块统一API接口，提供utils模块的统一调用接口和依赖管理。
#       作者: 林再来
#       日期: 2025-10-20
#       版本: 1.0
#       功能:
#           1、提供utils模块的统一调用接口
#           2、按需加载工具模块，避免不必要的模块加载
#           3、统一的错误处理和日志记录
#           4、模块依赖关系管理
#           5、支持直接调用和统一接口两种使用方式
#       依赖(插件/命令):
#           1、bash
#           2、各个utils_*.sh模块
###############################################################################

# 防止重复加载
if [[ -n "${utils_sh_loaded:-}" ]]; then
    return 0
fi
readonly utils_sh_loaded=1

# 注意：不使用严格模式，避免影响交互式 shell

# 获取脚本目录和项目根目录（如果尚未定义）
if [[ -z "${script_dir:-}" ]]; then
    script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    readonly script_dir
fi

if [[ -z "${project_root:-}" ]]; then
    project_root="$(cd "${script_dir}/../.." && pwd)"
    readonly project_root
fi

###############################################################################
# 全局常量
###############################################################################

# 模块分类管理
readonly -A UTILS_CATEGORIES=(
    ["datetime"]="utils_datetime.sh"
    ["file"]="utils_file.sh"
    ["email"]="utils_email.sh"
    ["validate"]="utils_validate.sh"
    ["jq"]="utils_jq.sh"
    ["yq"]="utils_yq.sh"
    ["character"]="utils_character.sh"
    ["number"]="utils_number.sh"
)

# 模块依赖关系
readonly -A UTILS_DEPENDENCIES=(
    ["email"]="validate,file"
    ["jq"]="validate"
    ["yq"]="validate"
)

###############################################################################
# 全局变量
###############################################################################

# 模块加载状态管理
declare -A _utils_loaded_modules

# 错误处理标志
_utils_error_handling_enabled=true

###############################################################################
# 核心功能函数
###############################################################################

# 函数: 按需加载工具模块
# 参数: $1 - 模块名称
# 返回: 0-成功, 1-失败
# 说明: 自动处理模块依赖关系，避免重复加载
function _utils_load_module() {
    local module="$1"
    local module_file="${UTILS_CATEGORIES[$module]:-}"
    
    # 检查模块是否存在
    if [[ -z "$module_file" ]]; then
        echo "错误: 未知的工具模块: $module" >&2
        return 1
    fi
    
    # 检查是否已加载
    if [[ -n "${_utils_loaded_modules[$module]:-}" ]]; then
        return 0
    fi
    
    # 检查模块文件是否存在
    local module_path="${script_dir}/${module_file}"
    if [[ ! -f "$module_path" ]]; then
        echo "错误: 模块文件不存在: $module_path" >&2
        return 1
    fi
    
    # 处理模块依赖
    local dependencies="${UTILS_DEPENDENCIES[$module]:-}"
    if [[ -n "$dependencies" ]]; then
        IFS=',' read -r -a deps <<< "$dependencies"
        for dep in "${deps[@]}"; do
            dep=$(echo "$dep" | xargs) # 去除空格
            _utils_load_module "$dep" || return $?
        done
    fi
    
    # 加载模块
    if source "$module_path"; then
        _utils_loaded_modules[$module]=1
        if [[ "${_utils_error_handling_enabled}" == "true" ]]; then
            echo "[DEBUG] 已加载模块: $module" >&2
        fi
        return 0
    else
        echo "错误: 加载模块失败: $module" >&2
        return 1
    fi
}

# 函数: 统一调用接口
# 参数: $1 - 模块类别, $2 - 函数名, $3... - 函数参数
# 返回: 函数执行结果
# 说明: 提供统一的utils模块调用接口
function utils() {
    local category="$1"
    local function_name="$2"
    shift 2
    
    # 参数校验
    if [[ -z "$category" ]]; then
        echo "错误: 缺少模块类别参数" >&2
        echo "用法: utils <category> <function> [args...]" >&2
        echo "可用类别: ${!UTILS_CATEGORIES[*]}" >&2
        return 64
    fi
    
    if [[ -z "$function_name" ]]; then
        echo "错误: 缺少函数名参数" >&2
        echo "用法: utils <category> <function> [args...]" >&2
        return 64
    fi
    
    # 加载模块
    if ! _utils_load_module "$category"; then
        return $?
    fi
    
    # 构建函数名
    local full_function_name="utils_${category}_${function_name}"
    
    # 检查函数是否存在
    if ! declare -F "$full_function_name" >/dev/null 2>&1; then
        echo "错误: 函数不存在: $full_function_name" >&2
        echo "提示: 请检查函数名是否正确" >&2
        return 1
    fi
    
    # 调用函数
    "$full_function_name" "$@"
}

# 函数: 列出所有可用的工具模块
# 参数: 无
# 返回: 0-成功
# 说明: 显示所有可用的工具模块和其功能
function utils_list_modules() {
    echo "可用的工具模块:"
    echo "=================="
    
    for category in "${!UTILS_CATEGORIES[@]}"; do
        local module_file="${UTILS_CATEGORIES[$category]}"
        local module_path="${script_dir}/${module_file}"
        
        if [[ -f "$module_path" ]]; then
            echo "✓ $category - $module_file"
        else
            echo "✗ $category - $module_file (文件不存在)"
        fi
    done
    
    echo ""
    echo "使用方法:"
    echo "  utils <category> <function> [args...]"
    echo "  例如: utils datetime format '2025-01-01' '%Y-%m-%d'"
}

# 函数: 列出指定模块的所有函数
# 参数: $1 - 模块类别
# 返回: 0-成功, 1-失败
# 说明: 显示指定模块的所有可用函数
function utils_list_functions() {
    local category="$1"
    
    if [[ -z "$category" ]]; then
        echo "错误: 缺少模块类别参数" >&2
        echo "用法: utils_list_functions <category>" >&2
        return 64
    fi
    
    # 加载模块
    if ! _utils_load_module "$category"; then
        return $?
    fi
    
    echo "模块 '$category' 的可用函数:"
    echo "=========================="
    
    # 获取所有以 utils_${category}_ 开头的函数
    local prefix="utils_${category}_"
    while IFS= read -r func; do
        if [[ "$func" =~ ^declare[[:space:]]+-f[[:space:]]+${prefix}(.+)$ ]]; then
            local func_name="${BASH_REMATCH[1]}"
            echo "  $func_name"
        fi
    done < <(declare -F | grep "^declare -f ${prefix}")
}

# 函数: 检查模块是否已加载
# 参数: $1 - 模块名称
# 返回: 0-已加载, 1-未加载
# 说明: 检查指定模块是否已被加载
function utils_is_loaded() {
    local module="$1"
    [[ -n "${_utils_loaded_modules[$module]:-}" ]]
}

# 函数: 获取已加载的模块列表
# 参数: 无
# 返回: 0-成功
# 说明: 显示当前已加载的所有模块
function utils_loaded_modules() {
    if [[ ${#_utils_loaded_modules[@]} -eq 0 ]]; then
        echo "当前没有加载任何模块"
        return 0
    fi
    
    echo "已加载的模块:"
    echo "============="
    for module in "${!_utils_loaded_modules[@]}"; do
        echo "  ✓ $module"
    done
}

# 函数: 启用/禁用调试模式
# 参数: $1 - true/false
# 返回: 0-成功
# 说明: 控制是否显示模块加载的调试信息
function utils_set_debug() {
    local enabled="$1"
    if [[ "$enabled" == "true" ]]; then
        _utils_error_handling_enabled=true
        echo "调试模式已启用"
    else
        _utils_error_handling_enabled=false
        echo "调试模式已禁用"
    fi
}

# 函数: 获取utils模块版本信息
# 参数: 无
# 返回: 0-成功
# 说明: 显示utils模块的版本信息
function utils_version() {
    echo "Utils模块统一API接口"
    echo "版本: 1.0"
    echo "作者: 林再来"
    echo "日期: 2025-01-02"
    echo ""
    echo "支持的模块:"
    for category in "${!UTILS_CATEGORIES[@]}"; do
        echo "  - $category"
    done
}

###############################################################################
# 便捷函数（常用操作的快捷方式）
###############################################################################

# 函数: 快速格式化日期时间
# 参数: $1 - 日期时间字符串, $2 - 格式（可选）
# 返回: 格式化后的日期时间
# 说明: 提供日期时间格式化的快捷方式
function utils_date_format() {
    utils datetime format "$@"
}

# 函数: 快速复制文件
# 参数: $1 - 源文件, $2 - 目标文件
# 返回: 0-成功, 1-失败
# 说明: 提供文件复制的快捷方式
function utils_copy() {
    utils file copy "$@"
}

# 函数: 快速验证参数
# 参数: $1 - 参数值, $2 - 参数名
# 返回: 0-通过, 1-失败
# 说明: 提供参数验证的快捷方式
function utils_validate() {
    utils validate required "$@"
}

# 函数: 快速发送邮件
# 参数: $1 - 收件人, $2 - 主题, $3 - 内容
# 返回: 0-成功, 1-失败
# 说明: 提供邮件发送的快捷方式
function utils_send_email() {
    utils email send "$@"
}

###############################################################################
# 帮助和文档函数
###############################################################################

# 函数: 显示帮助信息
# 参数: 无
# 返回: 0-成功
# 说明: 显示utils模块的详细帮助信息
function utils_help() {
    cat << 'EOF'
Utils模块统一API接口 - 帮助信息
================================

基本用法:
  utils <category> <function> [args...]

可用类别:
  datetime  - 日期时间处理工具
  file      - 文件操作工具
  email     - 邮件发送工具
  validate  - 数据校验工具
  jq        - JSON数据处理工具
  yq        - YAML数据处理工具
  character - 字符串处理工具
  number    - 数字处理工具

管理命令:
  utils_list_modules      - 列出所有可用模块
  utils_list_functions    - 列出指定模块的函数
  utils_loaded_modules    - 显示已加载的模块
  utils_is_loaded         - 检查模块是否已加载
  utils_set_debug         - 启用/禁用调试模式
  utils_version           - 显示版本信息
  utils_help              - 显示此帮助信息

便捷函数:
  utils_date_format       - 快速格式化日期时间
  utils_copy              - 快速复制文件
  utils_validate          - 快速验证参数
  utils_send_email        - 快速发送邮件

使用示例:
  # 格式化日期时间
  utils datetime format "2025-01-01" "%Y-%m-%d"
  
  # 复制文件
  utils file copy "/source/file.txt" "/dest/file.txt"
  
  # 验证参数
  utils validate required "$value" "参数名"
  
  # 发送邮件
  utils email send "user@example.com" "主题" "内容"

直接调用方式（保持兼容）:
  source "${project_root}/scripts/utils/utils_datetime.sh"
  utils_datetime_format "2025-01-01" "%Y-%m-%d"

更多信息请参考各模块的详细文档。
EOF
}

# 如果脚本直接运行，显示帮助信息
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    case "${1:-help}" in
        "help"|"-h"|"--help")
            utils_help
            ;;
        "version"|"-v"|"--version")
            utils_version
            ;;
        "list"|"-l"|"--list")
            utils_list_modules
            ;;
        *)
            echo "用法: $0 [help|version|list]"
            echo "  help    - 显示帮助信息"
            echo "  version - 显示版本信息"
            echo "  list    - 列出所有模块"
            ;;
    esac
fi
